package com.tanhua.server.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.dubbo.server.api.SoundApi;
import com.tanhua.dubbo.server.pojo.Sound;
import com.tanhua.server.pojo.User;
import com.tanhua.server.pojo.UserInfo;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.SoundUploadResult;
import com.tanhua.server.vo.SoundVo;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Service
public class SoundService {

    @Reference(version = "1.0.0")
    private SoundApi soundApi;


    @Autowired
    private SoundUploadService soundUploadService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String CACHE_KEY_FREEZE_PREFIX = "FREEZE_KEY_";


    public String saveSound(MultipartFile soundFile) {
        //获取当前用户
        User user = UserThreadLocal.get();

        String reqSaveSound = redisTemplate.opsForValue().get(CACHE_KEY_FREEZE_PREFIX + user.getId().toString());
        if("2".equals(reqSaveSound)){
            return null;
        }
        //创建一个音频对象
        Sound sound = new Sound();
        //设置用户id
        sound.setUserId(user.getId());

        //上传音频到阿里云
        SoundUploadResult upload = soundUploadService.upload(soundFile);
        //将路径添加到sound对象
        sound.setSoundUrl(upload.getName());

        //发送音频
        return soundApi.saveSound(sound);


    }

    public SoundVo getSound() {
        //获取当前用户
        User user = UserThreadLocal.get();
        //获取当前用户id
        Long myUserId = user.getId();
        //查询所有sound,不包含自己发送的
        List<Sound> soundList = soundApi.querySoundList(myUserId);
        //非空判断
        if (soundList.size() == 0) {
            return null;
        }
        //创建一个集合保存所有sound的id
        ArrayList<String> soundIdList = new ArrayList<String>();
        for (Sound sound : soundList) {
            ObjectId soundId = sound.getId();
            soundIdList.add(soundId.toString());
        }
        //从redis中获取的sound的id字符串
        String redisSoundListStr = redisTemplate.opsForValue().get("SOUND_GET_" + myUserId);
        //定义一个sounds集合
        ArrayList<String> sounds;
        //首次设置判断
        if (null == redisSoundListStr) {
            sounds = new ArrayList<>();

        } else {
            //先转换为数组
            String[] strs0 = redisSoundListStr.split(",");
            //再转换为集合
            sounds = new ArrayList<>(Arrays.asList(strs0));
        }


        //调用方法,获取一个不重复的sound,把它的soundId存到redis中
        getRandomSound(sounds, soundIdList, myUserId);

        //维护剩余次数
        //获取某用户对应次数和key的剩余时间
        String timeStr = redisTemplate.opsForValue().get("SOUND_GET_TIME_" + myUserId);
        Long expire = redisTemplate.getExpire("SOUND_GET_TIME_" + myUserId, TimeUnit.SECONDS);
        //判断是否为空
        if (null == timeStr) {
            //设置存在时长
            redisTemplate.opsForValue().set("SOUND_GET_TIME_" + myUserId, "9", 24, TimeUnit.HOURS);
        } else {
            int time = Integer.parseInt(timeStr);
            redisTemplate.opsForValue().set("SOUND_GET_TIME_" + myUserId, String.valueOf(time - 1), expire, TimeUnit.SECONDS);
        }


        //存储完后从redis中获取新的redisSoundList集合
        String redisSoundListStr2 = redisTemplate.opsForValue().get("SOUND_GET_" + myUserId);
        String[] strs = redisSoundListStr2.split(",");
        List<String> soundList2 = new ArrayList<>(Arrays.asList(strs));

        //集合最后一个元素便是最新的
        String soundId = soundList2.get(soundList2.size() - 1);
        //通过soundId找到sound
        Sound sound = soundApi.queryById(soundId);
        //获取sound的userId,从而获得发送sound的用户详细信息
        Long userId = sound.getUserId();
        //通过sound的userId,从而获得发送sound的用户详细信息
        UserInfo userInfo = userInfoService.queryById(userId);
        //非空判断
        if (null == userInfo) {
            return null;
        }
        //创建一个soundVo对象用于返回
        SoundVo soundVo = new SoundVo();
        //设置各项属性
        soundVo.setId(userId.intValue());
        soundVo.setAge(userInfo.getAge());
        soundVo.setAvatar(userInfo.getLogo());
        soundVo.setGender(userInfo.getSex().toString());
        soundVo.setNickname(userInfo.getNickName());
        soundVo.setSoundUrl(sound.getSoundUrl());

//        int count=10;//每天可用次数
        String timeStr2 = redisTemplate.opsForValue().get("SOUND_GET_TIME_" + myUserId);
        //剩余次数
        soundVo.setRemainingTimes(Integer.valueOf(timeStr2));
        //返回
        return soundVo;

    }


    //利用递归获取一个不重复的sound的方法
    public void getRandomSound(ArrayList<String> sounds, List<String> soundIdList, Long userId) {
        //如果集合长度相等则返回,防止无限递归
        if (sounds.size() == soundIdList.size()) {
            return;
        }
        //从集合中随机获取一个元素
        int i = RandomUtils.nextInt(0, soundIdList.size());
        String soundId = soundIdList.get(i);
        //不重复变添加进去
        if (!sounds.contains(soundId)) {
            sounds.add(soundId);
            //转换为字符串
            String redisSoundListStr2 = StringUtils.join(sounds, ",");
            redisTemplate.opsForValue().set("SOUND_GET_" + userId, redisSoundListStr2);
        } else {
            //递归
            getRandomSound(sounds, soundIdList, userId);
        }
    }


}